package dk.mirasola.systemtraining.bridgewidgets.shared.model;

import com.google.gwt.user.client.rpc.IsSerializable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Hand implements IsSerializable {
    public static final Suit[] SUITS = new Suit[]{Suit.SPADE, Suit.HEART, Suit.DIAMOND, Suit.CLUB};

    public static Hand create(Set<Card> cards,boolean validateAndCopy) {
        Hand hand = new Hand();
        if (validateAndCopy) {
            hand.cards.addAll(cards);
            if (hand.cards.size() > 13) {
                throw new RuntimeException("A hand can only contain 13 cards");
            }
        } else {
            hand.cards = cards;
        }
        return hand;
    }

    private Set<Card> cards = new HashSet<Card>();

    public Hand() {
    }

    public Set<Card> getCards() {
        return Collections.unmodifiableSet(cards);
    }

    public Set<Card> getCards(Suit suit) {
        HashSet<Card> res = new HashSet<Card>();
        addCardsInSuit(suit, res);
        return res;
    }

    private void addCardsInSuit(Suit suit, Collection<Card> res) {
        for (Card card : cards) {
            if (card.getSuit() == suit) {
                res.add(card);
            }
        }
    }

    public List<Card> getCardsSorted(Suit suit) {
        List<Card> cards = new ArrayList<Card>();
        addCardsInSuit(suit, cards);
        if (cards.size() > 0) {
            Collections.sort(cards);
        }
        return cards;
    }

    public int getCardsCount() {
        return cards.size();
    }

    public int getCardsCount(Suit suit) {
        int res = 0;
        for (Card card : cards) {
            if (card.getSuit() == suit) {
                res++;
            }
        }
        return res;
    }

    public int getHcp() {
        int res = 0;
        for (Card card : cards) {
            res += card.getHcp();
        }
        return res;
    }

    public int getHcp(Suit suit) {
        int res = 0;
        for (Card card : cards) {
            if (card.getSuit() == suit) {
                return res;
            }
        }
        return res;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Hand)) return false;

        Hand hand = (Hand) o;
        return cards.equals(hand.getCards());
    }

    @Override
    public int hashCode() {
        return cards.hashCode();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(16);
        for (Suit suit : SUITS) {
            List<Card> cards = getCardsSorted(suit);
            if (cards.size() == 0) {
                sb.append("-");
            } else {
                for (Card card : cards) {
                    sb.append(card.getRang());
                }
            }

            if (suit != Suit.CLUB) {
                sb.append(" ");
            }
        }
        return sb.toString();
    }
}
